﻿#include "customplot.h"

CustomPlot::CustomPlot(QWidget* parent)
	: QCustomPlot(parent)
	, is_large_(false)
	, max_point_count_(700)
	, pre_assist_cross_state_(false)
	, select_start_line_(Q_NULLPTR)
	, select_end_line_(Q_NULLPTR)
	, analyze_state_(AnalyzeState_NoAction)
{
	//设置拖拽
	setAcceptDrops(true);
	setMouseTracking(true);
	setContextMenuPolicy(Qt::CustomContextMenu); //设置自定义菜单

	setBackground(Qt::transparent);
	setStyleSheet("background:transparent;");

	legend->setVisible(false);

	// 设置轴标签
	xAxis->setLabel("");// QStringLiteral("时间(h)"));
	yAxis->setLabel("");
	// 设置上边和右边轴没有刻度和标签
	// xAxis->setVisible(false);
	//yAxis->setVisible(false);//坐标轴是否可见
	//xAxis->setTicks(true);//刻度是否可见
	yAxis->setTicks(true);
	yAxis->setTickLabels(true);//轴标签是否可见
	//xAxis->setTickLabels(false); 
	QPen pen_x = xAxis->basePen();
	pen_x.setColor(Qt::white);
	xAxis->setTickPen(pen_x);
	xAxis->setBasePen(pen_x);
	QPen pen_y = xAxis->basePen();
	pen_y.setColor(Qt::white);
	yAxis->setTickPen(pen_y);
	yAxis->setBasePen(pen_y);

	xAxis->setLabelColor(Qt::white);
	yAxis->setLabelColor(Qt::white);

	xAxis->setTickLabelColor(Qt::white);
	yAxis->setTickLabelColor(Qt::white);

	//setInteractions(1);//不可拖动
	setInteractions(QCP::iSelectPlottables);
	setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
	xAxis->setNumberFormat("gbc");//g灵活的格式,b漂亮的指数形式，c乘号改成×



	//辅助线层
	addLayer(QStringLiteral("assist_cross"));
	QCPLayer* cross_layer = layer(QStringLiteral("assist_cross"));
	cross_layer->setVisible(true);
	assist_cross_ = new AssistCross(this);
	assist_cross_->setLayer(QStringLiteral("assist_cross"));
	axisRect()->setRangeZoom(Qt::Horizontal | Qt::Vertical);
	axisRect()->setRangeDrag(Qt::Horizontal | Qt::Vertical);
	//标签层
	addLayer(QStringLiteral("mark_layer"));
	QCPLayer* mark_layer = layer(QStringLiteral("mark_layer"));
	mark_layer->setVisible(true);
	mark_layer_ = new MarkLayer(this);
	mark_layer_->setLayer(QStringLiteral("mark_layer"));


	connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange)));
	connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange)));
	connect(this, &CustomPlot::customContextMenuRequested, this, &CustomPlot::PlotWidgetCustomContextMenu);
	connect(this, &CustomPlot::plottableClick, this, &CustomPlot::SelectPlottableClick);
	connect(this, &CustomPlot::plottableDoubleClick, this, &CustomPlot::SelectPlottableDoubleClick);
	//右键菜单
	menu_ = new QMenu;
	edit_title_ = new QAction(QStringLiteral("修改标题"));
	action_lsNone_ = new QAction(QStringLiteral("无连接线"));
	action_lsLine_ = new QAction(QStringLiteral("直线连接"));
	action_lsStepLeft_ = new QAction(QStringLiteral("阶梯线(左数据点对齐)"));
	action_lsStepRight_ = new QAction(QStringLiteral("阶梯线(右数据点对齐)"));
	action_lsImpulse_ = new QAction(QStringLiteral("脉冲线"));
	action_mark_enable_ = new QAction(QStringLiteral("标签模式"));
	action_mark_enable_->setCheckable(true);
	action_create_auto_mark_ = new QAction(QStringLiteral("快捷标签"));
	action_create_manual_mark_ = new QAction(QStringLiteral("手动标签"));
	action_setting_rect_ = new QAction(QStringLiteral("设置显示区域"));
	action_recover_rect_ = new QAction(QStringLiteral("恢复全区域视图"));
	action_enable_assist_cross_ = new QAction(QStringLiteral("启用辅助线"));
	action_enable_assist_cross_->setCheckable(true);
	action_wheel_zoom_ = new QAction(QStringLiteral("滚轮缩放"));
	//action_wheel_zoom_->setCheckable(true);
	//action_wheel_zoom_->setChecked(true);
	action_selection_rect_zoom_ = new QAction(QStringLiteral("区域框选"));
	action_selection_rect_zoom_->setCheckable(true);
	choose_time_atcion_ = new QAction(QStringLiteral("曲线分析"));
	choose_time_atcion_->setCheckable(true);
	clear_current_view_action_ = new QAction(QStringLiteral("清除当前视图"));
	action_cut_picture = new QAction(QStringLiteral("截图"));
	menu_->addAction(edit_title_);
	menu_->addSeparator();
	menu_->addAction(action_lsNone_);
	menu_->addAction(action_lsLine_);
	menu_->addAction(action_lsStepLeft_);
	menu_->addAction(action_lsStepRight_);
	menu_->addAction(action_lsImpulse_);
	menu_->addSeparator();
	menu_->addAction(action_mark_enable_);
	menu_->addAction(action_create_auto_mark_);
	menu_->addAction(action_create_manual_mark_);
	menu_->addSeparator();
	menu_->addAction(action_setting_rect_);
	menu_->addAction(action_recover_rect_);
	menu_->addSeparator();
	menu_->addAction(action_enable_assist_cross_);
	menu_->addSeparator();
	//menu_->addAction(action_wheel_zoom_);
	//menu_->addAction(action_selection_rect_zoom_);
	menu_->addAction(choose_time_atcion_);
	menu_->addSeparator();
	menu_->addAction(clear_current_view_action_);
	menu_->addAction(action_cut_picture);
	connect(edit_title_, &QAction::triggered, this, &CustomPlot::EidtTitleText);
	connect(action_lsNone_, &QAction::triggered, this, &CustomPlot::SetLineStyleAction);
	connect(action_lsLine_, &QAction::triggered, this, &CustomPlot::SetLineStyleAction);
	connect(action_lsStepLeft_, &QAction::triggered, this, &CustomPlot::SetLineStyleAction);
	connect(action_lsStepRight_, &QAction::triggered, this, &CustomPlot::SetLineStyleAction);
	connect(action_lsImpulse_, &QAction::triggered, this, &CustomPlot::SetLineStyleAction);
	connect(action_mark_enable_, &QAction::toggled, this, &CustomPlot::SetMarkEnable);
	connect(action_create_auto_mark_, &QAction::triggered, this, &CustomPlot::CreateAutoMarkAction);
	connect(action_create_manual_mark_, &QAction::triggered, this, &CustomPlot::CreateManualMarkAction);
	connect(action_setting_rect_, &QAction::triggered, this, &CustomPlot::SetRectAction);
	connect(action_recover_rect_, &QAction::triggered, this, &CustomPlot::DisplayAllRect);
	connect(action_enable_assist_cross_, &QAction::toggled, this, &CustomPlot::SetEnableAssistCrossAction);
	connect(action_wheel_zoom_, &QAction::toggled, this, &CustomPlot::SetWheelZoomAction);
	connect(action_selection_rect_zoom_, &QAction::toggled, this, &CustomPlot::SetSelectionRectZoomAction);
	connect(choose_time_atcion_, &QAction::triggered, this, &CustomPlot::ChooseTime);
	connect(clear_current_view_action_, &QAction::triggered, this, &CustomPlot::ClearCurrentViewAction);
	connect(action_cut_picture, &QAction::triggered, this, &CustomPlot::CutPictureAction);

	action_max_value_ = new QAction(QStringLiteral("最大值"));
	action_min_value_ = new QAction(QStringLiteral("最小值"));
	action_average_value_ = new QAction(QStringLiteral("平均值"));
	action_std_dev_ = new QAction(QStringLiteral("标准差"));
	menu_->addSeparator();
	menu_->addAction(action_max_value_);
	menu_->addAction(action_min_value_);
	menu_->addAction(action_average_value_);
	menu_->addAction(action_std_dev_);
	//分析功能菜单使能--不可用
	action_max_value_->setVisible(false);
	action_min_value_->setVisible(false);
	action_average_value_->setVisible(false);
	action_std_dev_->setVisible(false);
	connect(action_max_value_, &QAction::triggered, this, &CustomPlot::MaxValue);
	connect(action_min_value_, &QAction::triggered, this, &CustomPlot::MinValue);
	connect(action_average_value_, &QAction::triggered, this, &CustomPlot::AverageValue);
	connect(action_std_dev_, &QAction::triggered, this, &CustomPlot::StandardDeviation);

}

CustomPlot::~CustomPlot()
{

}

void CustomPlot::ApplyDrawConfig(const PlotSettingConfig& config)
{
	config_ = config;
	//标题文字颜色
	QColor _kPlotTitleTextColor(config.color_title_font.toUInt(NULL, 16));
	title_->setTextColor(_kPlotTitleTextColor);
	//辅助十字架色
	//辅助十字架背景色
	//辅助线文字色
	assist_cross_->SetAssistColor(config.color_assist_line, config.color_assist_background);
	//标点标签背景色
	mark_layer_->SetColor(config.color_mark_background);
	//面板背景色
	QColor _kPlotBackgroundColor(config.color_background.toUInt(NULL, 16));
	setBackground(_kPlotBackgroundColor);

	QColor _kPlotAxisColor(config.color_axis.toUInt(NULL, 16));
	//坐标轴颜色
	xAxis->setBasePen(QPen(_kPlotAxisColor));
	yAxis->setBasePen(QPen(_kPlotAxisColor));
	//坐标轴字体颜色
	QColor _kPlotAxisFontColor(config.color_axis_font.toUInt(NULL, 16));
	xAxis->setLabelColor(_kPlotAxisFontColor);
	yAxis->setLabelColor(_kPlotAxisFontColor);
	//网格线色
	QColor _kPlotGridColor(config.color_grid_line.toUInt(NULL, 16));
	xAxis->grid()->setPen(QPen(_kPlotGridColor));
	yAxis->grid()->setPen(QPen(_kPlotGridColor));

	xAxis->setTickLabelColor(_kPlotAxisColor);
	yAxis->setTickLabelColor(_kPlotAxisColor);
	xAxis->setTickPen(QPen(_kPlotAxisColor));
	yAxis->setTickPen(QPen(_kPlotAxisColor));
	xAxis->setSubTickPen(QPen(_kPlotAxisColor));
	yAxis->setSubTickPen(QPen(_kPlotAxisColor));

	legend->setBrush(QBrush(QColor(255, 255, 255, 0)));
	legend->setBorderPen(QPen(QColor(255, 255, 255, 0)));
	legend->setVisible(true);
	axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignRight | Qt::AlignTop);

	if (graphCount() != 0)
	{
		//多曲线颜色
		for (int i = 0; i < graphCount(); ++i)
		{
			QCPGraph* gh = graph(i);
			QCPAbstractLegendItem* legend_item = legend->item(legend->itemCount() - 1);
			//曲线属性
			QCPScatterStyle scatter_style;
			scatter_style.setSize(config_.point_size);
			gh->setScatterStyle(scatter_style);
			//曲线颜色
			int pre_color_count = config.plots_color.count();
			QString clr_str = config.plots_color[i % pre_color_count];
			QColor clr(clr_str.toUInt(NULL, 16));
			legend_item->setTextColor(clr);
			QPen pen(clr);
			pen.setWidth(config_.line_width);
			gh->setPen(pen);
			//辅助大标签的曲线名称显示颜色
			assist_cross_->RemoveTracer(gh->name().toStdString());
			assist_cross_->SetTracer(gh, gh->name().toStdString());
		}
	}
	//辅助线使能设置
	action_enable_assist_cross_->setChecked(config_.cursor_guide_enable);
	assist_cross_->Enable(config_.cursor_guide_enable);
	assist_cross_->setVisible(config_.cursor_guide_enable);

	replot(QCustomPlot::rpQueuedReplot);
}

void CustomPlot::PresettingView(const QString& xName, const QStringList& yNames)
{
	for (int i = 0; i < yNames.count(); ++i)
	{
		QCPGraph* graph = addGraph();
		QCPAbstractLegendItem* legend_item = legend->item(legend->itemCount() - 1);
		//曲线颜色
		int pre_color_count = config_.plots_color.count();
		QString clr_str = config_.plots_color.at(i % pre_color_count);
		QColor clr(clr_str.toUInt(NULL, 16));
		legend_item->setTextColor(clr);
		//默认使用曲线模式
		QCPScatterStyle scatter_style;
		scatter_style.setSize(config_.point_size);
		scatter_style.setShape(QCPScatterStyle::ssNone);
		graph->setScatterStyle(scatter_style);
		QPen pen(clr);
		QBrush brush(QColor(clr.red(), clr.green(), clr.blue(), 0x0f));
		graph->setPen(pen);
		graph->setName(yNames.at(i));
		assist_cross_->SetTracer(graph, yNames.at(i).toStdString());
	}
	legend->setVisible(true);
	axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignRight | Qt::AlignTop);//图例位置
}

void CustomPlot::AddPlotData(const QString& name, const QVector<double>& xs, const QVector<double>& ys)
{
	for (int i = 0; i < graphCount(); ++i)
	{
		QCPGraph* gh = graph(i);
		if (gh->name() == name)
		{
			gh->addData(xs, ys);

			double right = xs.at(0);// .gh->dataCount();

			double left = right - 10;

			QCPRange range(left, right);
			SetRange(range);




			//计算曲线范围
//bool is_xfound = false;
//QCPRange temp_xrange = gh->getKeyRange(is_xfound);
//if (!is_xfound) return;
//bool is_yfound = false;
//QCPRange temp_yrange = gh->getValueRange(is_yfound);
//if (!is_yfound) return;
//if (plots_rect_.isNull())
//{
//	plots_rect_.setLeft(temp_xrange.lower);
//	plots_rect_.setRight(temp_xrange.upper);
//	plots_rect_.setBottom(temp_yrange.lower);
//	plots_rect_.setTop(temp_yrange.upper);
//}
//else
//{
//	plots_rect_.setLeft(temp_xrange.lower < plots_rect_.left() ? temp_xrange.lower : plots_rect_.left());
//	plots_rect_.setRight(temp_xrange.upper > plots_rect_.right() ? temp_xrange.upper : plots_rect_.right());
//	plots_rect_.setBottom(temp_yrange.lower < plots_rect_.bottom() ? temp_yrange.lower : plots_rect_.bottom());
//	plots_rect_.setTop(temp_yrange.upper > plots_rect_.top() ? temp_yrange.upper : plots_rect_.top());
//}



//if ( this->isVisible())
//	DisplayAllRect();//调整显示范围
			break;
		}
	}

	//QCPrange range();
}

void CustomPlot::AddNewPlot(const QString& name, const QVector<double>& xs, const QVector<double>& ys)
{
	if (name != "")
	{
		if (!curve->plots.contains(name))
			curve->plots.append(name);
	}

	int plot_count = graphCount();
	QCPGraph* gh = addGraph();
	QCPAbstractLegendItem* legend_item = legend->item(legend->itemCount() - 1);
	//曲线颜色
	int pre_color_count = config_.plots_color.count();
	QString clr_str = config_.plots_color[plot_count % pre_color_count];
	QColor clr(clr_str.toUInt(NULL, 16));
	legend_item->setTextColor(clr);
	//默认使用曲线模式
	gh->setLineStyle(QCPGraph::LineStyle::lsLine);
	QCPScatterStyle scatter_style;
	scatter_style.setSize(config_.point_size);
	scatter_style.setShape(QCPScatterStyle::ssNone);
	if (xs.count() <= max_point_count_)
	{
		//	scatter_style.setShape(QCPScatterStyle::ssDisc);
	}
	gh->setScatterStyle(scatter_style);

	QPen pen(clr);
	pen.setWidth(config_.line_width);
	gh->setPen(pen);
	gh->setName(name);
	assist_cross_->SetTracer(gh, name.toStdString());
	gh->setData(xs, ys);
	//replot();
	////
	// 
	QCPAxis* xAxis = gh->keyAxis();
	QCPAxis* yAxis = gh->valueAxis();

	//    配置下轴显示日期和时间，而不是数字：
	QSharedPointer<QCPAxisTickerDateTime> dateTick(new QCPAxisTickerDateTime);
	dateTick->setDateTimeFormat("MM-dd");
	xAxis->setTicker(dateTick);
	// 设置一个更紧凑的字体大小为底部和左轴刻度标签：
	xAxis->setTickLabelFont(QFont(QFont().family(), 8));
	xAxis->setTickLabelFont(QFont(QFont().family(), 8));

	// 设置轴标签
	//xAxis->setLabel(QStringLiteral("时间(h)"));
	//yAxis->setLabel("值");

	// 设置上边和右边轴没有刻度和标签
	xAxis->setVisible(true);
	xAxis->setTickLabels(true);//轴标签是否可见

	yAxis->setVisible(true);//坐标轴是否可见
	//xAxis->setTicks(true);//刻度是否可见
	yAxis->setTicks(true);
	yAxis->setTickLabels(false);//轴标签是否可见

	//xAxis->setTickLabels(false); 
	QPen pen_x = xAxis->basePen();
	pen_x.setColor(Qt::white);
	xAxis->setTickPen(pen_x);
	xAxis->setBasePen(pen_x);

	xAxis->setTickLabelColor(Qt::white);
	yAxis->setTickLabelColor(Qt::white);

	QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);//日期做X轴
	dateTicker->setDateTimeFormat("mm:ss");//日期格式(可参考QDateTime::fromString()函数)
	dateTicker->setDateTimeSpec(Qt::UTC);

	dateTicker->setTickCount(3600 * 24); // 一天的秒数
	dateTicker->setTickCount(3);//一个大刻度包含4个小刻度
	xAxis->setTicker(dateTicker);//设置X轴为时间轴

	////
	//计算曲线范围
	bool is_xfound = false;
	QCPRange temp_xrange = gh->getKeyRange(is_xfound);
	if (!is_xfound) return;
	bool is_yfound = false;
	QCPRange temp_yrange = gh->getValueRange(is_yfound);
	if (!is_yfound) return;
	if (plots_rect_.isNull())
	{
		plots_rect_.setLeft(temp_xrange.lower);
		plots_rect_.setRight(temp_xrange.upper);
		plots_rect_.setBottom(temp_yrange.lower);
		plots_rect_.setTop(temp_yrange.upper);
	}
	else
	{
		plots_rect_.setLeft(temp_xrange.lower < plots_rect_.left() ? temp_xrange.lower : plots_rect_.left());
		plots_rect_.setRight(temp_xrange.upper > plots_rect_.right() ? temp_xrange.upper : plots_rect_.right());
		plots_rect_.setBottom(temp_yrange.lower < plots_rect_.bottom() ? temp_yrange.lower : plots_rect_.bottom());
		plots_rect_.setTop(temp_yrange.upper > plots_rect_.top() ? temp_yrange.upper : plots_rect_.top());
	}
	DisplayAllRect();
}

void CustomPlot::RemovePlot(const QString& name)
{
	for (int i = 0; i < graphCount(); ++i)
	{
		if (graph(i)->name() == name)
		{
			assist_cross_->RemoveTracer(name.toStdString());
			removeGraph(i);
		}
	}
	replot(QCustomPlot::rpQueuedReplot);
}

void CustomPlot::RemoveAllPlots()
{
	for (int i = 0; i < graphCount(); ++i)
	{
		assist_cross_->RemoveTracer(graph(i)->name().toStdString());
		removeGraph(i);
	}
	replot(QCustomPlot::rpQueuedReplot);
}


void CustomPlot::SetRange(QCPRange range)
{

	xAxis->setRange(range);//x轴联动
	//y轴显示合适的区域-显示x范围内的所有y范围
	QCPRange yrange;
	for (int i = 0; i < graphCount(); ++i)
	{
		QCPGraph* gh = graph(i);
		bool found = false;
		QCPRange y_range = gh->getValueRange(found, QCP::sdBoth, range);//获取range范围内的y范围
		if (!found) continue;//没找到数据点
		if (i == 0)
		{
			yrange = y_range;
		}
		else
		{
			yrange.upper = y_range.upper > yrange.upper ? y_range.upper : yrange.upper;//取大
			yrange.lower = y_range.lower < yrange.lower ? y_range.lower : yrange.lower;//取小
		}
	}
	yAxis->setRange(yrange);
	layer("main")->replot();

}

void CustomPlot::SetAssistCrossEnable(bool enable)
{
	pre_assist_cross_state_ = enable;
	assist_cross_->Enable(enable);
	assist_cross_->setVisible(enable);
	replot(QCustomPlot::rpQueuedReplot);
	if (action_enable_assist_cross_->isChecked() != enable)
	{
		action_enable_assist_cross_->setChecked(enable);
	}
}

void CustomPlot::SetCurveInteractions(bool enable)
{
	//if (enable)
	//{
	//	setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
	//}
	//else
	//{
	//	//setInteractions(0);
	//	setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
	//}
}

void CustomPlot::SetPosInLayout(QPoint pos)
{
	pos_ = pos;
}

QPoint CustomPlot::GetPosInLayout()
{
	return pos_;
}

void CustomPlot::PlotRecoverDefaultDisplay()
{
	if (!plots_rect_.isNull())
	{
		if (plots_rect_.left() == plots_rect_.right())
		{
			xAxis->setRange(plots_rect_.left() - 10, plots_rect_.right() + 10);
		}
		else if (plots_rect_.left() < plots_rect_.right())
		{
			xAxis->setRange(plots_rect_.left() - qAbs(plots_rect_.width() / 100), plots_rect_.right() + qAbs(plots_rect_.width() / 100));
		}
		if (plots_rect_.bottom() == plots_rect_.top())
		{
			yAxis->setRange(plots_rect_.bottom() - 10, plots_rect_.top() + 10);
		}
		else
		{
			yAxis->setRange(plots_rect_.bottom() - qAbs(plots_rect_.height() / 10), plots_rect_.top() + qAbs(plots_rect_.height() / 10));
		}
	}
	else
	{
		xAxis->setRange(0, 5);
		yAxis->setRange(0, 5);
	}
	replot(QCustomPlot::rpQueuedReplot);
}

void CustomPlot::SetCurveConfig(CurveConfig* cc)
{
	this->curve = cc;

	SetTitle(curve->curve_name);

}

void CustomPlot::SetTitle(const QString& text)
{
	//设置标题
	if (title_)
	{
		title_->setText(text.isEmpty() ? QString(QUuid::createUuid().toByteArray().mid(2, 5)) : text);
	}
	replot(QCustomPlot::rpQueuedReplot);
}

const QString CustomPlot::GetTitle()
{
	return title_->text();
}

void CustomPlot::CancelAnalyze()
{

}

void CustomPlot::SetMarkEnable(bool enable)
{
	if (enable)//标签模式下，禁用辅助线功能，否则导致选点事件无法触发
	{
		//setSelectionRectMode(QCP::SelectionRectMode::srmSelect); //选择框模式：选取数据
		//setMultiSelectModifier(Qt::KeyboardModifier::ControlModifier);//多选按键Ctrl
		//setInteractions(interactions() | QCP::iMultiSelect);

		for (int i = 0; i < graphCount(); ++i)
		{
			QCPGraph* gh = graph(i);
			gh->setSelection(QCPDataSelection());//清空选中
			gh->setSelectable(QCP::SelectionType::stSingleData);//数据单选
		}
	}
	else
	{
		//setSelectionRectMode(QCP::SelectionRectMode(~QCP::SelectionRectMode::srmSelect)); //选择框模式：选取数据
		//setMultiSelectModifier(Qt::KeyboardModifier(~Qt::KeyboardModifier::ControlModifier));//多选按键Ctrl
		//setInteractions(interactions() | QCP::Interactions(~QCP::iMultiSelect));
		for (int i = 0; i < graphCount(); ++i)
		{
			QCPGraph* gh = graph(i);
			gh->setSelectable(QCP::SelectionType::stWhole);
		}
	}
	if (action_mark_enable_->isChecked() != enable)
	{
		action_mark_enable_->setChecked(enable);
	}
	mark_current_graph_ = NULL;
	mark_current_point_ = QPointF();
}

void CustomPlot::SetLarge(bool isLarge)
{
	is_large_ = isLarge;
}

bool CustomPlot::IsLarge()
{
	return is_large_;
}

void CustomPlot::mouseDoubleClickEvent(QMouseEvent* event)
{
	emit DoubleClickedSignal();
	QCustomPlot::mouseDoubleClickEvent(event);
}

void CustomPlot::PlotWidgetCustomContextMenu(const QPoint& pos)
{
	QList<QCPGraph*> ghs = selectedGraphs();
	action_lsNone_->setEnabled(!ghs.isEmpty());
	action_lsLine_->setEnabled(!ghs.isEmpty());
	action_lsStepLeft_->setEnabled(!ghs.isEmpty());
	action_lsStepRight_->setEnabled(!ghs.isEmpty());
	action_lsImpulse_->setEnabled(!ghs.isEmpty());
	if (action_mark_enable_->isChecked() && mark_current_graph_ != NULL)//判断标点模式
	{
		action_create_auto_mark_->setEnabled(mark_current_graph_->selected());//是否有点被选中
		action_create_manual_mark_->setEnabled(mark_current_graph_->selected());//是否有点被选中
	}
	else
	{
		action_create_auto_mark_->setEnabled(action_mark_enable_->isChecked() && mark_current_graph_ != NULL);//是否启用标记使能
		action_create_manual_mark_->setEnabled(action_mark_enable_->isChecked() && mark_current_graph_ != NULL);//是否启用标记使能
	}
	menu_->exec(QCursor::pos());
}

void CustomPlot::wheelEvent(QWheelEvent* event)
{
	QCPRange range = this->xAxis->range();
	//判断范围内曲线点是否小于最大点数
	bool is_show_ssDisc = false;
	for (int i = 0; i < graphCount(); ++i)
	{
		if (graph(i)->findBegin(range.upper) - graph(i)->findBegin(range.lower) <= max_point_count_)
		{
			is_show_ssDisc = true;
			break;
		}
	}
	if (is_show_ssDisc)
	{
		QCPScatterStyle scatter_style;
		scatter_style.setSize(config_.point_size);
		scatter_style.setShape(QCPScatterStyle::ssDisc);
		for (int i = 0; i < graphCount(); ++i)
		{
			QCPGraph* gh = graph(i);
			gh->setScatterStyle(scatter_style);
		}
	}
	else
	{
		QCPScatterStyle scatter_style;
		scatter_style.setSize(config_.point_size);
		scatter_style.setShape(QCPScatterStyle::ssNone);
		for (int i = 0; i < graphCount(); ++i)
		{
			QCPGraph* gh = graph(i);
			gh->setScatterStyle(scatter_style);
		}
	}
	//选中轴进行缩放
	static int i = 0;
	i++;
	if (xAxis->selectedParts().testFlag(QCPAxis::spAxis))
	{
		axisRect()->setRangeZoom(xAxis->orientation());
	}
	else if (yAxis->selectedParts().testFlag(QCPAxis::spAxis))
	{
		axisRect()->setRangeZoom(yAxis->orientation());
	}
	else
		axisRect()->setRangeZoom(Qt::Horizontal | Qt::Vertical);
	QCustomPlot::wheelEvent(event);
}

void CustomPlot::enterEvent(QEvent* event)
{
	assist_cross_->SetAssistTipVisible(true);
}

void CustomPlot::leaveEvent(QEvent* event)
{
	assist_cross_->SetAssistTipVisible(false);
}

void CustomPlot::mousePressEvent(QMouseEvent* event)
{
	//鼠标中键框选
	if (event->button() == Qt::MidButton)
	{
		//模式：框选放大
		setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
		selectionRect()->setPen(QPen(Qt::black, 1, Qt::DashLine));//虚线
		selectionRect()->setBrush(QBrush(QColor(0, 0, 100, 50)));//半透明浅蓝
	}
	//单击选点
	if (action_mark_enable_->isChecked())
	{
		if (action_enable_assist_cross_->isChecked())
		{
			SetAssistCrossEnable(false); //禁用辅助线功能
		}
	}

	if (analyze_state_ == AnalyzeState_NoAction)
	{
		setCursor(Qt::ClosedHandCursor);
	}
	else
	{
		//判断是否右键选中时间选择起始线
		double distance = select_start_line_->selectTest(event->pos(), false);
		//这个是像素点小于3
		if (distance < 3 && event->button() == Qt::LeftButton)
		{
			analyze_state_ = AnalyzeState_SelectStartLine;
			setCursor(Qt::PointingHandCursor);
		}
		//判断右键是否选中时间选择结束线
		distance = select_end_line_->selectTest(event->pos(), false);
		if (distance < 3 && event->button() == Qt::LeftButton)
		{
			if (analyze_state_ == AnalyzeState_SelectStartLine)
			{
				analyze_state_ = AnalyzeState_SelectBothLine;
			}
			else
			{
				analyze_state_ = AnalyzeState_SelectEndLine;
			}
			setCursor(Qt::PointingHandCursor);
		}
	}
	QCustomPlot::mousePressEvent(event);
}

void CustomPlot::mouseReleaseEvent(QMouseEvent* event)
{

	if (analyze_state_ == AnalyzeState_SelectStartLine || analyze_state_ == AnalyzeState_SelectEndLine)
	{
		analyze_state_ = AnalyzeState_StartAnalyze;
	}
	//鼠标中键款选
	if (event->button() == Qt::MidButton)
	{
		setSelectionRectMode(QCP::SelectionRectMode::srmNone);
		//获取被框选的区域，并设置
		QCPRange x_range = selectionRect()->range(xAxis);
		QCPRange y_range = selectionRect()->range(yAxis);
		xAxis->setRange(x_range);
		yAxis->setRange(y_range);
		layer("main")->replot();
	}
	//单击选点
	if (action_mark_enable_->isChecked())
	{
		SetAssistCrossEnable(action_enable_assist_cross_->isChecked()); //禁用辅助线功能
	}
	setCursor(Qt::ArrowCursor);
	QCustomPlot::mouseReleaseEvent(event);
}

void CustomPlot::mouseMoveEvent(QMouseEvent* event)
{
	switch (analyze_state_)
	{
	case AnalyzeState_NoAction:
	{
		QCustomPlot::mouseMoveEvent(event);
		break;
	}
	case AnalyzeState_StartSelectLine:
	{
		QCustomPlot::mouseMoveEvent(event);
		break;
	}
	case AnalyzeState_SelectStartLine:
	{
		double x_vaule = this->xAxis->pixelToCoord(event->pos().x());

		if (x_vaule > select_end_line_->point1->coords().x())
		{
			x_vaule = select_end_line_->point1->coords().x();
		}
		//更新线
		select_start_line_->point1->setCoords(x_vaule, 7);
		select_start_line_->point2->setCoords(x_vaule, 2);

		this->replot(QCustomPlot::rpQueuedReplot);
		break;
	}
	case AnalyzeState_SelectEndLine:
	{
		double pos_x_vaule = this->xAxis->pixelToCoord(event->pos().x());

		//设置结束时间线的拖动范围
		if (pos_x_vaule < select_start_line_->point1->coords().x())
		{
			pos_x_vaule = select_start_line_->point1->coords().x();
		}

		//更新线
		select_end_line_->point1->setCoords(pos_x_vaule, 8);
		select_end_line_->point2->setCoords(pos_x_vaule, 2);

		this->replot(QCustomPlot::rpQueuedReplot);
		break;
	}
	case AnalyzeState_SelectBothLine:
	{
		double pos_x_vaule = this->xAxis->pixelToCoord(event->pos().x());

		double line_x_value = select_end_line_->point1->key();
		//移动结束线
		if (pos_x_vaule > line_x_value)
		{
			select_end_line_->point1->setCoords(pos_x_vaule, 8);
			select_end_line_->point2->setCoords(pos_x_vaule, 2);
			analyze_state_ = AnalyzeState_SelectEndLine;
		}
		//移动起始线
		else
		{
			select_start_line_->point1->setCoords(pos_x_vaule, 8);
			select_start_line_->point2->setCoords(pos_x_vaule, 2);
			analyze_state_ = AnalyzeState_SelectStartLine;
		}
		this->replot(QCustomPlot::rpQueuedReplot);
		break;
	}
	case AnalyzeState_StartAnalyze:
		QCustomPlot::mouseMoveEvent(event);
		break;
	default:
		break;
	}
}

void CustomPlot::SetAssstTipPos(int x, int y)
{
	assist_cross_->SetAssistTipWidgetPos(x, y);
}

void CustomPlot::ShowAssistTip()
{
	assist_cross_->SetAssistTipVisible(true);
}

void CustomPlot::hideAssistTip()
{
	assist_cross_->SetAssistTipVisible(false);
}

void CustomPlot::DisplayAllRect()
{
	if (!plots_rect_.isNull())
	{
		if (plots_rect_.left() == plots_rect_.right())
		{
			xAxis->setRange(plots_rect_.left() - 10, plots_rect_.right() + 10);
		}
		else if (plots_rect_.left() < plots_rect_.right())
		{
			xAxis->setRange(plots_rect_.left() - qAbs(plots_rect_.width() / 100), plots_rect_.right() + qAbs(plots_rect_.width() / 100));
		}
		if (plots_rect_.bottom() == plots_rect_.top())
		{
			yAxis->setRange(plots_rect_.bottom() - 10, plots_rect_.top() + 10);
		}
		else
		{
			yAxis->setRange(plots_rect_.bottom() - qAbs(plots_rect_.height() / 10), plots_rect_.top() + qAbs(plots_rect_.height() / 10));
		}
	}
	else
	{
		//	xAxis->setRange(0, 5);
		//	yAxis->setRange(0, 5);
	}

	replot(QCustomPlot::rpQueuedReplot);
}

void CustomPlot::EidtTitleText()
{
	EditTitleDialog* dialog = new EditTitleDialog(this);
	connect(dialog, &EditTitleDialog::EditFinishedSignal, [=](const QString text)
		{
			SetTitle(text);
		});
	dialog->SetText(title_->text());
	dialog->exec();
}

void CustomPlot::SetLineStyleAction()
{
	QList<QCPGraph*> ghs = selectedGraphs();
	QAction* action = qobject_cast<QAction*>(sender());
	if (action == action_lsNone_)
	{
		foreach(auto & gh, ghs)
		{
			gh->setLineStyle(QCPGraph::LineStyle::lsNone);
		}
	}
	else if (action == action_lsLine_)
	{
		foreach(auto & gh, ghs)
		{
			gh->setLineStyle(QCPGraph::LineStyle::lsLine);
		}
	}
	else if (action == action_lsStepLeft_)
	{
		foreach(auto & gh, ghs)
		{
			gh->setLineStyle(QCPGraph::LineStyle::lsStepLeft);
		}
	}
	else if (action == action_lsStepRight_)
	{
		foreach(auto & gh, ghs)
		{
			gh->setLineStyle(QCPGraph::LineStyle::lsStepRight);
		}
	}
	else if (action == action_lsImpulse_)
	{
		foreach(auto & gh, ghs)
		{
			gh->setLineStyle(QCPGraph::LineStyle::lsImpulse);
		}
	}
	replot(QCustomPlot::rpQueuedReplot);
}


void CustomPlot::CreateAutoMarkAction()
{
	//读取启用的快捷标点配置
// 	QPair<QString, QStringList> regulation = DCFileHandler::GetInstance().GetMarkRegulationConfig();
// 	QString name_regulation = regulation.first;//名称规则
// 	name_regulation.replace("%p%", "%1");
// 	QString tip_name = name_regulation.arg(mark_layer_->GetMarkTipCount() + 1);
// 	QStringList tip_attr = regulation.second;
// 	GenerateMarkTip(tip_name, tip_attr);
}

void CustomPlot::CreateManualMarkAction()
{
	// 	DCMarkBindDialog* dialog = new DCMarkBindDialog(this);//标点绑定
	// 	connect(dialog, &DCMarkBindDialog::MarkBindFinishedSignal, this, &DCQCustomPlot::GenerateMarkTip);//标点绑定完成信号槽
	// 	dialog->SetAlreadyAttr(DCFileHandler::GetInstance().GetMarkAttrScriptConfig());//设置已有属性
	// 	dialog->exec();
}

void CustomPlot::GenerateMarkTip(const QString& tip_name, const QStringList& tip_attr, const QString& tip_note)
{
	// 	QList<QPair<QString, QString>> attr_script_list =DCFileHandler::GetInstance().GetMarkAttrScriptConfig();//获取属性脚本
	// 	QMap<QString, QString> attr_script_map;//便于使用，转换为map
	// 	foreach(auto& attr_script, attr_script_list)
	// 	{
	// 		attr_script_map.insert(attr_script.first, attr_script.second);
	// 	}
	// 	//标签名称+曲线+点、属性+值
	// 	QStringList text;
	// 	text.append(QStringLiteral("[%1] - %2(%3,%4)").arg(tip_name).arg(mark_current_graph_->name()).arg(mark_current_point_.x()).arg(mark_current_point_.y()));
	// 	foreach(auto& attr, tip_attr)
	// 	{
	// 		Q_ASSERT(attr_script_map.contains(attr));
	// 		QString script = attr_script_map.value(attr);
	// 		double v = ExecuteAttrScript(script, mark_current_point_);
	// 		text.append(QStringLiteral("%1：%2").arg(attr).arg(v));
	// 	}
	// 	if (!tip_note.isEmpty())
	// 	{
	// 		//标签备注，手动标签下存在
	// 		text.append(tip_note);
	// 	}
	// 	mark_layer_->CreateMarkTip(mark_current_graph_, mark_current_point_, text);
	// 	mark_current_graph_ = NULL;
	// 	mark_current_point_ = QPointF();
}

double CustomPlot::ExecuteAttrScript(QString script, QPointF p)
{
	QScriptEngine engine;
	engine.globalObject().setProperty("PX", p.x());
	engine.globalObject().setProperty("PY", p.y());
	engine.globalObject().setProperty("px", p.x());
	engine.globalObject().setProperty("py", p.y());
	QScriptValue v = engine.evaluate(script);
	return v.toNumber();
}

void CustomPlot::SetRectAction()
{
	SettingPlotRectDialog* dialog = new SettingPlotRectDialog(this);
	dialog->SetCurrentRect(xAxis->range(), yAxis->range());
	connect(dialog, &SettingPlotRectDialog::OkClickedSignal, [=](const QCPRange& xRange, const QCPRange& yRange)
		{
			xAxis->setRange(xRange);
			yAxis->setRange(yRange);
			replot(QCustomPlot::rpQueuedReplot);
		});
	dialog->exec();
}

void CustomPlot::SetEnableAssistCrossAction(bool checked)
{
	assist_cross_->Enable(checked);
	assist_cross_->setVisible(checked);
}

void CustomPlot::SetWheelZoomAction(bool checked)
{
	if (checked)
	{
		action_selection_rect_zoom_->setChecked(false);
		setSelectionRectMode(QCP::SelectionRectMode::srmNone);
	}
}

void CustomPlot::SetSelectionRectZoomAction(bool checked)
{
	//if (checked)
	//{
	//	//模式：框选放大
	//	setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
	//	selectionRect()->setPen(QPen(Qt::black, 1, Qt::DashLine));//虚线
	//	selectionRect()->setBrush(QBrush(QColor(0, 0, 100, 50)));//半透明浅蓝
	//}
	//else
	//{
	//	setSelectionRectMode(QCP::SelectionRectMode::srmNone);
	//}
}


void CustomPlot::ChooseTime(bool checked)
{
	if (checked)
	{
		QPoint pos = mapFromGlobal(QCursor::pos());

		if (select_start_line_)
		{
			select_start_line_->setVisible(false);
			this->removeItem(select_start_line_);
		}
		if (select_end_line_)
		{
			select_end_line_->setVisible(false);
			this->removeItem(select_end_line_);
		}

		select_start_line_ = new QCPItemStraightLine(this);
		select_start_line_->setSelectable(true);
		select_start_line_->setPen(QPen(Qt::blue, 4));
		select_start_line_->point1->setCoords(plots_rect_.x(), 0);
		select_start_line_->point2->setCoords(plots_rect_.x(), 1);

		select_end_line_ = new QCPItemStraightLine(this);
		select_end_line_->setSelectable(true);
		select_end_line_->setPen(QPen(Qt::blue, 4));
		select_end_line_->point1->setCoords(plots_rect_.x() + plots_rect_.width(), 0);
		select_end_line_->point2->setCoords(plots_rect_.x() + plots_rect_.width(), 1);

		//禁用辅助线
		assist_cross_->Enable(false);
		assist_cross_->setVisible(false);
		//分析状态-开始分析
		analyze_state_ = AnalyzeState_StartSelectLine;
		//分析功能菜单使能--可用
		action_max_value_->setVisible(true);
		action_min_value_->setVisible(true);
		action_average_value_->setVisible(true);
		action_std_dev_->setVisible(true);
	}
	else
	{
		//分析状态置空
		analyze_state_ = AnalyzeState_NoAction;
		select_start_line_->setVisible(false);
		this->removeItem(select_start_line_);
		select_start_line_ = Q_NULLPTR;
		select_end_line_->setVisible(false);
		this->removeItem(select_end_line_);
		select_end_line_ = Q_NULLPTR;
		//还原辅助线状态
		SetAssistCrossEnable(pre_assist_cross_state_);
		//分析功能菜单使能--不可用
		action_max_value_->setVisible(false);
		action_min_value_->setVisible(false);
		action_average_value_->setVisible(false);
		action_std_dev_->setVisible(false);
	}
	replot(QCustomPlot::rpQueuedReplot);
}

void CustomPlot::ClearCurrentViewAction()
{
	emit ClearCurrentViewSignal(pos_);
}

void CustomPlot::CutPictureAction()
{
	//保存图片
	QString path = QString("../CutPicture/%1_%2").arg(title_->text()).arg(QDateTime::currentDateTime().toString(" yyyy-MM-dd hh-mm-ss.png"));
	bool is_saved = savePng(path);
	if (!is_saved)
	{
		return;
	}
	//拷贝到剪切板
	QClipboard* board = QApplication::clipboard();
	board->setPixmap(QPixmap(path));
}

void CustomPlot::dragEnterEvent(QDragEnterEvent* event)
{
	QDragEnterEvent* drag_enter_event = static_cast<QDragEnterEvent*>(event);
	if (drag_enter_event->mimeData()->hasFormat("drag_view_event")
		|| drag_enter_event->mimeData()->hasFormat("drag_variables_event"))
	{
		drag_enter_event->setDropAction(Qt::MoveAction);
		drag_enter_event->accept();
	}
	else
	{
		drag_enter_event->ignore();
	}
}

void CustomPlot::dragMoveEvent(QDragMoveEvent* event)
{
	QDragMoveEvent* drag_move_event = static_cast<QDragMoveEvent*>(event);
	if (drag_move_event->mimeData()->hasFormat("drag_view_event")
		|| drag_move_event->mimeData()->hasFormat("drag_variables_event"))
	{
		drag_move_event->setDropAction(Qt::MoveAction);
		drag_move_event->accept();
	}
	else
	{
		drag_move_event->ignore();
	}
}

void CustomPlot::dropEvent(QDropEvent* event)
{
	QDropEvent* drop_event = static_cast<QDropEvent*>(event);
	if (drop_event->mimeData()->hasFormat("drag_view_event"))
	{
		QByteArray item_data = drop_event->mimeData()->data("drag_view_event");
		QDataStream data_stream(&item_data, QIODevice::ReadOnly);
		QPoint drag_pos;
		data_stream >> drag_pos;
		drop_event->setDropAction(Qt::MoveAction);
		drop_event->accept();
		if (drag_pos != pos_)
		{
			//发送视图位置调换信号
			emit ViewPosExchangedSignal(drag_pos, pos_);
		}
	}
	else if (drop_event->mimeData()->hasFormat("drag_variables_event"))
	{
		QByteArray item_data = drop_event->mimeData()->data("drag_variables_event");
		QDataStream data_stream(&item_data, QIODevice::ReadOnly);
		QStringList variable_name_list;
		data_stream >> variable_name_list;
		foreach(const QString & variable_name, variable_name_list)
			AddNewPlot(variable_name, QVector<qreal>(), QVector<qreal>());
		drop_event->setDropAction(Qt::MoveAction);
		drop_event->accept();
	}
	else
	{
		drop_event->ignore();
	}
}

void CustomPlot::MinValue()
{
	double start_x = select_start_line_->point1->key();
	double end_x = select_end_line_->point1->key();
	for (int gc = 0; gc < graphCount(); ++gc)
	{
		const QCPGraph* gh = graph(gc);
		emit SendMessageSignal(QStringLiteral("分析曲线[%1]在%2 ~ %3范围内的最小值：").arg(gh->name()).arg(start_x).arg(end_x));
		std::vector<QCPGraphData> min_datas;
		QSharedPointer<QCPDataContainer<QCPGraphData> > graph_data = gh->data();
		for (int i = 0; i < gh->dataCount(); ++i)
		{
			if (graph_data.data()->at(i)->key < start_x)
			{
				continue;
			}
			if (graph_data.data()->at(i)->key > end_x)
			{
				break;
			}
			if (min_datas.empty())
			{
				min_datas.push_back(*graph_data.data()->at(i));
			}
			else
			{
				if (graph_data.data()->at(i)->value == min_datas[0].value)
				{
					min_datas.push_back(*graph_data.data()->at(i));
				}
				else if (graph_data.data()->at(i)->value < min_datas[0].value)
				{
					min_datas.clear();
					min_datas.push_back(*graph_data.data()->at(i));
				}
				else
				{
				}
			}
		}
		if (min_datas.empty())
		{
			emit SendMessageSignal(QStringLiteral("分析结果出错:[分析结果为空]"));
		}
		else
		{
			foreach(const auto & min_data, min_datas)
			{
				emit SendMessageSignal(QString(QStringLiteral("x值为：%1，出现最小值：%2")).arg(min_data.key).arg(min_data.value));
			}
		}
	}
	emit SendMessageSignal(QString());
}

void CustomPlot::MaxValue()
{
	double start_x = select_start_line_->point1->key();
	double end_x = select_end_line_->point1->key();
	for (int gc = 0; gc < graphCount(); ++gc)
	{
		QCPGraph* gh = graph(gc);
		emit SendMessageSignal(QStringLiteral("分析曲线[%1]在%2 ~ %3范围内的最大值：").arg(gh->name()).arg(start_x).arg(end_x));
		std::vector<QCPGraphData> max_datas;
		QSharedPointer<QCPDataContainer<QCPGraphData>>  graph_data = gh->data();
		for (int i = 0; i < gh->dataCount(); ++i)
		{
			if (graph_data.data()->at(i)->key < start_x)
			{
				continue;
			}
			if (graph_data.data()->at(i)->key > end_x)
			{
				break;
			}
			if (max_datas.empty())
			{
				max_datas.push_back(*graph_data.data()->at(i));
			}
			else
			{
				if (graph_data.data()->at(i)->value == max_datas[0].value)
				{
					max_datas.push_back(*graph_data.data()->at(i));
				}
				else if (graph_data.data()->at(i)->value > max_datas[0].value)
				{
					max_datas.clear();
					max_datas.push_back(*graph_data.data()->at(i));
				}
				else
				{
				}
			}
		}
		if (max_datas.empty())
		{
			emit SendMessageSignal(QStringLiteral("分析结果出错:[分析结果为空]"));
		}
		else
		{
			foreach(const auto & man_data, max_datas)
			{
				emit SendMessageSignal(QString(QStringLiteral("x值为：%1，出现最大值：%2")).arg(man_data.key).arg(man_data.value));
			}
		}
	}
	emit SendMessageSignal(QString());
}

void CustomPlot::AverageValue()
{
	double start_x = select_start_line_->point1->key();
	double end_x = select_end_line_->point1->key();
	for (int gc = 0; gc < graphCount(); ++gc)
	{
		QCPGraph* gh = graph(gc);
		emit SendMessageSignal(QStringLiteral("分析曲线[%1]在%2 ~ %3范围内的平均值：").arg(gh->name()).arg(start_x).arg(end_x));

		long double total_value = 0;
		QSharedPointer<QCPDataContainer<QCPGraphData>>  graph_data = gh->data();
		int count = 0;
		for (int i = 0; i < gh->dataCount(); ++i)
		{
			if (graph_data.data()->at(i)->key < start_x)
			{
				continue;
			}
			if (graph_data.data()->at(i)->key > end_x)
			{
				break;
			}
			total_value += graph_data.data()->at(i)->value;
			count++;
		}
		double average_data = total_value / count;
		emit SendMessageSignal(QString(QStringLiteral("平均值为：%1")).arg(average_data));
		emit SendMessageSignal(QString());
	}
}

void CustomPlot::Variance()
{
	double start_x = select_start_line_->point1->key();
	double end_x = select_end_line_->point1->key();
	for (int gc = 0; gc < graphCount(); ++gc)
	{
		QCPGraph* gh = graph(gc);
		emit SendMessageSignal(QStringLiteral("分析曲线[%1]在%2 ~ %3范围内的方差：").arg(gh->name()).arg(start_x).arg(end_x));
		QVector<long double> variance_value_vector;
		QSharedPointer<QCPDataContainer<QCPGraphData>>  graph_data = gh->data();
		int count = 0;
		for (int i = 0; i < gh->dataCount(); ++i)
		{
			if (graph_data.data()->at(i)->key < start_x)
			{
				continue;
			}
			if (graph_data.data()->at(i)->key > end_x)
			{
				break;
			}
			variance_value_vector.push_back(graph_data.data()->at(i)->value);
			count++;
		}
		double variance_value = GetVariance(variance_value_vector);
		emit SendMessageSignal(QString(QStringLiteral("方差为：%1")).arg(variance_value));
		emit SendMessageSignal(QString());
	}

}

double CustomPlot::GetVariance(QVector<long double> samples_vector)
{
	//(（样本平方 - 平均平方） ÷ n ）开方
	long double sum = 0;
	foreach(float sample, samples_vector)
	{
		sum += sample;
	}
	//平均值
	long double average = sum / samples_vector.size();

	long double accum = 0;
	foreach(float sample, samples_vector)
	{
		accum += qPow(sample - average, 2);
	}
	long double variance = accum / samples_vector.size();

	return variance;
}

void CustomPlot::StandardDeviation()
{
	double start_x = select_start_line_->point1->key();
	double end_x = select_end_line_->point1->key();
	for (int gc = 0; gc < graphCount(); ++gc)
	{
		QCPGraph* gh = graph(gc);
		emit SendMessageSignal(QStringLiteral("分析曲线[%1]在%2 ~ %3范围内的标准差：").arg(gh->name()).arg(start_x).arg(end_x));
		QVector<long double> samples_value_vector;
		QSharedPointer<QCPDataContainer<QCPGraphData>>  graph_data = gh->data();
		int count = 0;
		for (int i = 0; i < gh->dataCount(); ++i)
		{
			if (graph_data.data()->at(i)->key < start_x)
			{
				continue;
			}
			if (graph_data.data()->at(i)->key > end_x)
			{
				break;
			}
			samples_value_vector.push_back(graph_data.data()->at(i)->value);
			count++;
		}
		double samples_value = GetStandardDeviation(samples_value_vector);
		emit SendMessageSignal(QString(QStringLiteral("方差为：%1")).arg(samples_value));
		emit SendMessageSignal(QString());
	}
}

double CustomPlot::GetStandardDeviation(QVector<long double> samples_vector)
{
	long double sum = 0;
	foreach(float sample, samples_vector)
	{
		sum += sample;
	}
	//平均值
	long double average = sum / samples_vector.size();

	long double accum = 0;
	foreach(float sample, samples_vector)
	{
		accum += qPow(sample - average, 2);
	}
	long double standard_deviation = qSqrt(accum / samples_vector.size());

	return standard_deviation;
}

void CustomPlot::SelectPlottableClick(QCPAbstractPlottable* plottable, int dataIndex, QMouseEvent* event)
{
	if (!action_mark_enable_->isChecked()) return;
	QCPGraph* gh = qobject_cast<QCPGraph*>(plottable);
	const QCPGraphData* ghd = gh->data()->at(dataIndex);
	mark_current_graph_ = gh;
	mark_current_point_ = QPointF(ghd->key, ghd->value);
}

void CustomPlot::SelectPlottableDoubleClick(QCPAbstractPlottable* plottable, int dataIndex, QMouseEvent* event)
{

}

CPTextElement::CPTextElement(CustomPlot* parentPlot, const QString& text, const QFont& font)
	: QCPTextElement(parentPlot, text, font)
{
}

CPTextElement::~CPTextElement()
{

}

void CPTextElement::mousePressEvent(QMouseEvent* event, const QVariant& details)
{
	int picture_width = 100;
	QPainter painter;
	QFontMetrics font_metrics = painter.fontMetrics();

	int width = font_metrics.width(text()) + 15;
	if (picture_width < width)
	{
		picture_width = width;
	}
	QPixmap pixmap(picture_width, 30);
	pixmap.fill(Qt::white);
	painter.begin(&pixmap);
	painter.drawText(QPoint(8, 20), text());
	painter.end();

	QByteArray item_data;
	QDataStream data_stream(&item_data, QIODevice::WriteOnly);
	CustomPlot* p_plot = qobject_cast<CustomPlot*>(parentPlot());
	data_stream << p_plot->GetPosInLayout();

	QMimeData* mime_data = new QMimeData();
	mime_data->setData("drag_view_event", item_data);

	QDrag* drag = new QDrag(this);
	drag->setMimeData(mime_data);
	drag->setPixmap(pixmap);

	drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
}

EditTitleDialog::EditTitleDialog(QWidget* parent /*= 0*/)
	: QDialog(parent)
{
	setFixedWidth(200);
	setWindowTitle(QStringLiteral("标题修改"));
	line_edit_ = new QLineEdit(this);
	btn_ok_ = new QPushButton(QStringLiteral("修改"), this);
	btn_ok_->setFocusPolicy(Qt::NoFocus);
	btn_ok_->setMaximumWidth(50);
	connect(btn_ok_, &QPushButton::clicked, this, &EditTitleDialog::OK);
	QHBoxLayout* hbox = new QHBoxLayout;
	hbox->addWidget(line_edit_, 2);
	hbox->addWidget(btn_ok_, 1);
	setLayout(hbox);
}

EditTitleDialog::~EditTitleDialog()
{

}

void EditTitleDialog::SetText(const QString& text)
{
	line_edit_->setText(text);
	line_edit_->selectAll();
}

void EditTitleDialog::OK()
{
	close();
	emit EditFinishedSignal(line_edit_->text());
}
